/* $RCSFile: UserWindowMgmt.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/BLL/User/UserWindowMgmt.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:27  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Text;
using System.Web.UI;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

using AddonNice.BLL.Utils;
using AddonNice.BLL.UserConfig;


	//===============================================================================
	//	Business Logic Layer
	//	AddonNice.BLL.User
	// Class to manage the User's Session Information
	// Encapsulates the detailed settings for a specific User Session
	// Caveat :
	//      Serializing/Deserializing adds time. 
	//===============================================================================

namespace AddonNice.BLL.User
{
	/// <summary>
	/// Summary description for UserWindowMgmt.
	/// Server-side state management of user layout
	/// </summary>
	public class UserWindowMgmt : AddonNice.BLL.Base.BLLBase
	{
        #region Private Data

        private const string UKEY_ = "User_";
        private const string UDATAKEY_ = "_UserData_";
        private Guid uid_ = Guid.Empty;
        private UserLayoutMgr ul_mgr_ = null;

        #endregion

        /// <summary>
		/// Ctor of the user session
		/// </summary>
		/// <param name="uid"></param>
		public UserWindowMgmt(Guid uid)
		{
			string key              =   makeKey(uid);
			// our bag holder
			IWebBagHolder user_bag  = BagFactory.instance.create();
			// remember the user id;
			uid_                    = uid;
			// get the user layout information, if any
			ul_mgr_                 = this.deserialize(key, ref user_bag);
			// is it an annonymous user
			if ( ul_mgr_ == null )
			{
				// go create one for the user
				addSessionUser(uid, ref user_bag);
			}
				
		} // end of ctor

		#region Attributes

		/// <summary>
		/// Get list of modules
		/// </summary>
		public Hashtable Modules
		{
			get {	return this.ul_mgr_.Modules;}
		} // end of Modules

		/// <summary>
		/// Get the user layout manager
		/// </summary>
		public UserLayoutMgr LayoutManager
		{
			get { return this.ul_mgr_;}
		} // end of PagesLayoutManager

		#endregion

		#region Public Methods

		/// <summary>
		/// Does this module/key exists
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public bool Contains(int key)
		{
			return this.ul_mgr_.Contains(key);
		} // end of Contains

		/// <summary>
		/// Add a module setting
		/// </summary>
		/// <param name="ums"></param>
		public void Add(UserModuleSettings ums)
		{
			this.ul_mgr_.Add(ums);
			// serialize the data
			this.Serialize();
		} // end of Add

	
		///	<summary>
		///	Default property for accessing resources
		/// <param name="index">
		/// Index for the desired resource</param>
		/// <returns>
		/// Resource string value</returns>
		///</summary>

		public UserModuleSettings this[ int index ]
		{
			get 
			{
				return this.ul_mgr_[index];
			}
			set
			{
				this.ul_mgr_.Add(value);
			}
		}


		/// <summary>
		/// Remove module
		/// </summary>
		/// <param name="id"></param>
		public void Remove(int id)
		{
			this.ul_mgr_.Remove(id);
			// serialize the data
			this.Serialize();
		} // end of Remove

		#endregion

		#region Protected Modules
		/// <summary>
		/// Serialize data
		/// </summary>
		protected void Serialize()
		{
			// our bag holder
			IWebBagHolder user_bag = BagFactory.instance.create();
		
			string key = makeKey(uid_);

			// serialize the data
			this.serialize(key, ref user_bag);
		} // end of Serialize

		#endregion

		#region Private Modules


		/// <summary>
		/// Add user information layout to the session
		/// </summary>
		/// <param name="uid"> user id</param>
		/// <param name="user_bag"> Session Bag</param>
		private void addSessionUser(Guid uid, ref IWebBagHolder user_bag)
		{
			string key      = makeKey(uid);
			// create the user layout
			this.ul_mgr_    = new UserLayoutMgr();
			// serialize the data
			serialize(key,ref user_bag);

		} // end of addSessionUser

	
		/// <summary>
		/// Create a user id key  for the session
		/// </summary>
		/// <param name="uid"> user id </param>
		/// <returns>a user id string</returns>
		private string makeKey(Guid uid)
		{
			return UKEY_ + uid.ToString() + "_";

		} // end of makeKey

		/// <summary>
		/// Create a user id key  for the session's user data
		/// </summary>
		/// <param name="uid"> user id </param>
		/// <returns>a user id string</returns>
		private string makeUserDataKey(string uid)
		{
			return UDATAKEY_ + uid + "_";

		} // end of makeUserDataKey
	
		/// <summary>
		/// Serialize the user data
		/// </summary>
		/// <param name="key"></param>
		/// <param name="user_bag"></param>
		private void serialize(string key ,ref IWebBagHolder user_bag)
		{
			// goin into critical area
			lock(this.ul_mgr_)
			{
				MemoryStream ms     =   new MemoryStream();				
				BinaryFormatter bf  =   new BinaryFormatter ();
				bf.Serialize(ms,this.ul_mgr_);
                ms.Position         =   0;
				// add it to the bag
				user_bag[key]       =  Convert.ToBase64String(ms.ToArray());
			}
		} // end of serialize

		/// <summary>
		/// Deserialize the data to get the layout mgr.
		/// </summary>
		/// <param name="key"></param>
		/// <param name="user_bag"></param>
		/// <returns></returns>
		private UserLayoutMgr deserialize (string key, ref IWebBagHolder user_bag)
		{
			// get the user layout information, if any
			string   sdata = (string)user_bag[key];
			// any data
			if ( sdata != null && sdata.Length>0 )
			{
				// convert back to byte
				byte[] data = Convert.FromBase64String(sdata);
				// create the memory stream to serialize
				MemoryStream ms=new MemoryStream();
				// write data to the stream
				ms.Write(data,0,data.Length);
				// formatter 
				BinaryFormatter bf  =   new BinaryFormatter ();
				// set stream position to start
				ms.Position         =   0;
				// deserialize data
				return (UserLayoutMgr)bf.Deserialize(ms);
				
			}
			return null;
		} // end of deserialize

		#endregion

		/// <summary>
		///  Private Data Section
		/// </summary>


	}
}
